#include "server.hpp"

Server::Server()
{
    privateKey =  "../server/server-key.pem";
    localCertificate = "../server/server-crt.pem";

    // Initializes the server with default settings
    start(QHostAddress::Any, 45434);
}


Server::Server(quint16 port)
{
    start(QHostAddress::Any, port);
}

Server::~Server()
{}


void Server::start(QHostAddress host, quint16 port)
{
    // Listen for connexion
    listen(host, port);
}

void Server::incomingConnection(int socketDescriptor)
 {
     serverSocket = new QSslSocket;

     if(serverSocket->setSocketDescriptor(socketDescriptor))
     {
         // Load private key
         QFile file(privateKey);
         if( !file.open(QIODevice::ReadOnly))
         {
             // Debug
             display("Unable to open : " + privateKey);
             exit(0);
         }

         // passphrase : DefiQt
         QSslKey key(&file, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, "defiQt" );
         file.close();

         serverSocket->setPrivateKey(key);

         // Load certificate
         if( !serverSocket->addCaCertificates("../ca/ca.pem"))
         {
             // Debug
             display("Unable to open CA certificate : ../ca/ca.pem");
             exit(0);
         }

         // Load server's certificate
         serverSocket->setLocalCertificate(localCertificate);

         // Don't verify client's identity
         serverSocket->setPeerVerifyMode(QSslSocket::VerifyNone);

         // Connections and disconnections signals
         connect(serverSocket, SIGNAL(readyRead()), this, SLOT(read()));
         connect(serverSocket, SIGNAL(disconnected()), this, SLOT(disconnected()));

         serverSocket->ignoreSslErrors();
         serverSocket->startServerEncryption();
         
         display("New client connected.");
     }
     else
     {
         delete serverSocket;
     }
 }


void Server::read()
{
	// TODO : Stocker les clients pour les numeroter et les envoyer au debug (3 debugs).
	// TODO : gerer fermeture du server coté client.

    // Find who is sending
    QSslSocket *client = qobject_cast<QSslSocket*>(sender());

    // Print the sender
    //std::cout << "Client" << client << " is writing on the socket\n"; 
    display("A client is writing on the socket.");

    // If whe can't know who has sending data -> break
    if(client == 0)
        return;

    // Debug
    display("Client X : " + serverSocket->readAll());
}


void Server::disconnected()
{
    // Find who is disconnecting
    QSslSocket *client = qobject_cast<QSslSocket*>(sender());

    if(client == 0)
            return;

    // Print the sender
    //std::cout << "Client" << client << " is now disconnected\n";
    display("Client disconnected.");

    // Deletes the socket
    client->deleteLater();
}

void Server::display(QString s)
{
	qDebug() << s;
}
